#! /usr/bin/env python
# -*- coding: utf-8

from __future__ import unicode_literals
import os
import sys
import time
import datetime
import Tkinter
import codecs
import copy
from cStringIO import StringIO
import win32clipboard
from functools import partial
from PIL import Image, ImageTk
import Widgets



#sys.stdout = open("log.dat", 'w')



class MainWindow:
  def __init__(self, imagepath=r"Z:\NWP"):
    """
    initialled the root window
    """
    self._Version = "beta-0.354"
    self._Author =  "Laisky"
    self._Mail = "ppcelery@qq.com"


    print "MainWindow.__init__ be called"
    root = Tkinter.Tk()
    root.state('zoomed')
    products = {"climate": ["EC", "GFS", "T639"],
                "rain": ["GERMAN", "JAPAN"]}
    times = ["08", "20"]
    title = u'NWP\u663e\u793a\u5e73\u53f0 %s' % self._Version
    size = [root.winfo_screenwidth(), root.winfo_screenheight()]
    size = [int(size[0] * 0.8), int(size[1] * 0.8)]
    #pwd = os.path.dirname(sys.executable)
    #pwd = ''
    #pwd = u'G:\\dropbox\\Dropbox\\Backup\\codeSource\\qxt\\201208_02_display-the-product-of-shuzhiyubao\\\u4ea7\u54c1'
    #pwd = sys.path[0]
    pwd = (r'E:\laisky\dropbox\Dropbox\Backup\codeSource\qxt' \
           r'\201208_02_display-the-product-of-shuzhiyubao\dev')
    #pwd = r'G:\dropbox\Dropbox\Backup\codeSource\qxt\201208_02_display-the-product-of-shuzhiyubao\factor'
    try: pwd = pwd.decode('utf-8')
    except: pass
    try: pwd = pwd.decode('gbk')
    except: pass
    CanvasStatus = {"whether_full": '', "imgAlbum": {}, "grid": '', \
                    "date": '', "layer": '', "mode": '', 'region': '', \
                    "canvases": '', 'Draw_options': {"side": '', "size": '',\
                                                    "full": '', 'texts': {},\
                                                    "images": {}},\
                    "cavs_imgAlbum": {},
                   }
    self.layerTexts = {
        "C0": u'500hPa\u9ad8\u5ea6\u3001850hPa\u98ce\u573a\u3001\u76f8' \
              u'\u5bf9\u6e7f\u5ea6',
        "C1": u'700hPa\u98ce\u573a\u3001\u76f8\u5bf9\u6e7f\u5ea6',
        "C2": u'850hPa\u98ce\u573a\u3001\u76f8\u5bf9\u6e7f\u5ea6',
        "C3": u'500hPa\u9ad8\u5ea6\u3001850hPa\u6e29\u5ea6',
        "C4": u'\u6d77\u5e73\u9762\u6c14\u538b\u3001850hPa\u98ce\u573a' \
              u'\u3001\u76f8\u5bf9\u6e7f\u5ea6',
        "C5": u'\u6d77\u5e73\u9762\u6c14\u538b\u3001850hPa24\u5c0f' \
              u'\u65f6\u53d8\u6e29',
        "C6": u'24\u5c0f\u65f6\u53d8\u6e29',
        "C7": u'24\u5c0f\u65f6\u53d8\u538b',
        "C8": u'500hPa\u6d41\u573a',
        "C9": u'700hPa\u6d41\u573a',
        "C10": u'850hPa\u6d41\u573a',
        "C11": u'500hPa\u6da1\u5ea6',
        "C12": u'700hPa\u6da1\u5ea6',
        "C13": u'850hPa\u6da1\u5ea6',
        "C14": u'500hPa\u6563\u5ea6',
        "C15": u'700hPa\u6563\u5ea6',
        "C16": u'850hPa\u6563\u5ea6',
        }
    self.regionName = {
        "az": u'\u963f\u62c9\u5584\u5de6\u65d7',
        "lh": u'\u4e34\u6cb3',
        "ds": u'\u4e1c\u80dc',
        "wh": u'\u4e4c\u6d77',
        "bt": u'\u5305\u5934',
        "hhht": u'\u547c\u548c\u6d69\u7279',
        "jn": u'\u96c6\u5b81',
        "xlht": u'\u9521\u6797\u6d69\u7279',
        "cf": u'\u8d64\u5cf0',
        "tl": u'\u901a\u8fbd',
        "hle": u'\u6d77\u62c9\u5c14',
        "wlht": u'\u4e4c\u5170\u6d69\u7279',
        "zlc": u'\u7740\u843d\u573a',
        }
    regionName_order = ['az', 'lh', 'ds', 'wh', 'bt', 'hhht', 'jn', 'xlht', \
                        'cf', 'tl', 'hle', 'wlht', 'zlc']
    RainCateName = {'06': u'6\u5c0f\u65f6\u964d\u6c34\u9884\u62a5',\
                    '12': u'12\u5c0f\u65f6\u964d\u6c34\u9884\u62a5',\
                    '24': u'24\u5c0f\u65f6\u964d\u6c34\u9884\u62a5'}

    if pwd: pathfile = os.path.join(pwd, 'imagepath.dat')
    else: pathfile = "imagepath.dat"
    pathfile = self.pathSwitch(pathfile)
    if os.path.isfile(pathfile):
      the_path = open(pathfile, 'r').read().rstrip()
      try: the_path = the_path.decode('utf-8')
      except: pass
      try: the_path = the_path.decode('gbk')
      except: pass
      imgpath = self.pathSwitch(the_path)
      if os.path.exists(the_path): imagepath = the_path
      else: open(pathfile, 'w').write(imagepath.encode('utf-8'))
    else:
      open(pathfile, 'w').write(imagepath.encode('utf-8'))

    root.minsize(500, 400)
    root.config(bg="#363636")
    root.title(title)

    self.root = root
    self.Pwd = pwd
    self.imgPath = imagepath
    self.texts = {"def": u'\u7f3a\u7701'}
    self.canvasGrid = {"EC": "a1", "GFS": "b1", "T639": "a2", \
                       'GERMANY': 'a1', 'JAPAN': 'b1'}
    self.CanvasStatus = CanvasStatus
    self.regionName_order = regionName_order

    canvas = Widgets.myCanvas(root, CanvasStatus)
    toolbar = Widgets.myTollbar(root, funcs={
        "CanvasStatus": self.shuchu, "displayTexts": canvas.displayTexts,
        "PageDown": self.PageDown, "PageUp": self.PageUp,
        "SwitchTime": self.SwitchTime,},)
    menu = Widgets.myMenu(root) 
    
    the_imgpath = self.pathSwitch(imagepath)
    if not os.path.exists(the_imgpath):
      try: print "imagepath: '%s' not existed" % the_imgpath
      except: pass
      self.pathChange(master=root, pwd=pwd)
      root.mainloop()
      imagepath = open(pathfile, 'r').read().rstrip()
      if not os.path.exists(the_imgpath):
        os._exit(0)
      else: self.imgPath = imagepath

    #first interface
    the_date = self.lastdate("ec")
    if the_date: 
      self.CanvasStatus.update({"date": the_date, "layer": "C0", \
                                "mode": "climate"})
      name_a1 = self.date2name(the_date, "ec")
      name_a2 = self.nameRelate(the_date, cate="gfs")
      name_b1 = self.nameRelate(the_date, cate="T639")
      pics = self.name2pic([name_a1, name_a2, name_b1])
      texts = self.selectTexts(layer="C0", mode="climate")
    else:
      texts = {}
      pics = {}

    menu.Draw(texts = {"layerTexts": self.layerTexts,  \
                       "regionName": self.regionName, \
                       "regionName_order": regionName_order, \
                       "RainCateName": RainCateName}, \
              funcs={"labelFunc": self.labelFunc, \
                     "drawRegion": self.drawRegion, 'DrawRain': self.DrawRain,\
                     "About": self.About, "pathChange": self.pathChange, \
                     "pathSwitch": self.pathSwitch})
    toolbar.Draw()
    canvas.Draw(size=size, images=pics, texts=texts, \
                funcs = {"drawText": toolbar.drawText, \
                         "updateImagesize": self.updateImagesize, \
                         'Image2Clipboard': self.Image2Clipboard,}) \

    self.canvas = canvas
  
    root.mainloop()
    print "\tMainWindow initialled OK!"

  def pathChange(self, master=None, pwd=None):
    print "myMenu.pathChange be called"
    print "\t|master:", repr(master)
    print "\t|pwd:", repr(pwd)
    if master: top = master
    else: top = Tkinter.Toplevel()
    if pwd: pwd = pwd
    else: pwd = self.Pwd
    top.title(u'\u4fee\u6539\u8def\u5f84')
    frame1 = Tkinter.Frame(top)
    frame2 = Tkinter.Frame(top)
    frame1.pack(side=Tkinter.TOP)
    frame2.pack(side=Tkinter.TOP)
    hint = Tkinter.StringVar()
    entry_text = Tkinter.StringVar()
    hint.set(u'\u8f93\u5165\u8d44\u6599\u76ee\u5f55\u8def\u5f84' \
             u'\uff08\u5982\uff1a\\\\172.18.113.79\\data\\NWP\uff09')
    the_path = self.pathSwitch(os.path.join(pwd, 'imagepath.dat'))
    old_path = open(the_path, 'r').read().rstrip()
    try: old_path = old_path.decode('utf-8')
    except: pass
    try: old_path = old_path.decode('gbk')
    except: pass
    entry_text.set(old_path)
    Tkinter.Label(frame1, textvariable=hint).pack(side=Tkinter.TOP)
    Tkinter.Entry(frame2, textvariable=entry_text, width=80).pack(side=Tkinter.LEFT)
    check = partial(self.checkPath, top, hint, entry_text, pwd)
    Tkinter.Button(frame2, text=u'\u786e\u5b9a', command=check).pack(side=Tkinter.LEFT)
    exit = partial(os._exit, 0)
    #Button(frame2, text=u'\u9000\u51fa', command=exit).pack(side=LEFT)

  def checkPath(self, top, hint, entry_text, pwd):
    print "myMenu.checkPath be called"
    print '\t|top:', repr(top)
    print '\t|hint:', repr(hint)
    print '\t|entry_text:', repr(entry_text)
    print '\t|pwd:', repr(pwd)
    path = entry_text.get()
    if not path: return None
    img_path = self.pathSwitch(path)
    if os.path.exists(img_path):
      self.imgPath = path
      the_path = self.pathSwitch(os.path.join(pwd, 'imagepath.dat'))
      open(the_path, 'w').write(path.encode('utf-8'))
      hint.set(u'\u8def\u5f84\u4fee\u6539\u6210\u529f')
      top.destroy()
    else:
      hint.set(u'\u8d44\u6599\u76ee\u5f55\u4e0d\u5b58\u5728\uff0c\u8bf7' \
               u'\u91cd\u8bd5')
    return None

  def pathSwitch(self, path):
    print "MainWindow.pathSwitch be called"
    print '\t|path:', repr(path)
    if not isinstance(path, unicode):
      try: path = path.decode('gbk')
      except: pass
      try: path = path.decode('utf-8')
      except: pass
    if sys.platform == 'win32':
      return path.encode('gbk')
    else: return path.encode('utf-8')

  def About(self):
    author = self._Author
    version = self._Version
    mail = self._Mail
    return {'author': author, 'version': version, 'mail': mail}

  def drawRegion(self, region, date=None):
    print 'MainWindow.drawRegion be called'
    print '\t|region: %s\n\t|date: %s' % (repr(region), repr(date))
    if self.CanvasStatus['mode'] != 'REGION':
      self.CanvasStatus['whether_full'] = None
    full = self.CanvasStatus["whether_full"]
    if date: the_date = copy.deepcopy(date)
    else: the_date = self.lastdate("ec", region=region, layer="C17")
    if not the_date: the_date= self.lastdate('gfs', region=region, layer='C17')
    if not the_date: the_date= self.lastdate('gfs', region=region, layer='C18')
    if full and self.CanvasStatus['grid'] == 'a2': layer = 'C18'
    else: layer = 'C17'
    self.CanvasStatus.update({"date": the_date, "layer": layer, \
                              'mode': 'REGION', 'region': region})
    name_a1 = self.nameRelate(the_date, 'ec', layer="C17", region=region)
    name_b1 = self.nameRelate(the_date, 'gfs', layer='C17', region=region)
    name_a2 = self.nameRelate(the_date, 'gfs', layer='C18', region=region)
    self.CanvasStatus['imgAlbum'] = {}
    pics = self.name2pic([name_a1, name_b1, name_a2])
    texts = self.selectTexts(layer='C17', region=region, mode='region')
    size = self.CanvasStatus['Draw_options']['size']
    if full:
      grid = self.CanvasStatus['grid']
      cate = self.grid2cate(grid, mode='region')
      layer = self.grid2layer(grid)
      name_full = self.date2name(the_date, cate, layer=layer, region=region)
      pics.update(self.name2pic([name_full], full=full)) 
    self.canvas.Draw(size=size, images=pics, full=full, texts=texts)

  def DrawRain(self, layer, date=None):
    print "MainWindow.DrawRain be called"
    print "\t|layer: %s\n\t|date: %s" %(repr(layer), repr(date))
    if self.CanvasStatus['mode'] != 'RAIN': 
      self.CanvasStatus['whether_full'] = None
    grid = self.CanvasStatus['grid']
    full = self.CanvasStatus['whether_full']
    cate = self.grid2cate(grid=grid, mode='RAIN')
    if not full: cate = 'GERMANY'
    if not date: date = self.lastdate(cate='GERMANY', layer=layer)
    if not date: date = self.lastdate(cate='JAPAN', layer=layer)
    if not date: return None
    self.CanvasStatus.update({'date': date, 'layer': layer, 'mode': 'RAIN'})
    name_a1 = self.nameRelate(date=date, cate='GERMANY', layer=layer)
    name_b1 = self.nameRelate(date=date, cate='JAPAN', layer=layer)
    self.CanvasStatus['imgAlbum'] = {}
    pics = self.name2pic([name_a1, name_b1])
    texts = self.selectTexts(layer, mode="RAIN")
    size = self.CanvasStatus['Draw_options']['size']
    self.canvas.Draw(size=size, images=pics, full=full, texts=texts)

  def grid2layer(self, grid):
    print 'MainWindow.grid2layer be called'
    print '\t|grid:', repr(grid)
    grid = grid.lower()
    cate = self.grid2cate(grid, mode='region')
    cate = cate.upper()
    if cate == 'EC': return 'C17'
    elif cate == 'GFS':
      if grid == 'b1': return 'C17'
      elif grid == 'a2': return 'C18'

  def labelFunc(self, layer):
    print "MainWindow.labelFunc be called"
    print '\t|layer:', repr(layer)
    the_date = self.lastdate("ec", layer=layer)
    if not the_date: the_date = self.lastdate("GFS", layer=layer)
    if not the_date: the_date = self.lastdate("T639", layer=layer)
    self.CanvasStatus.update({"date": the_date, "layer": layer, \
                              'mode': "climate"})
    name_a1 = self.nameRelate(the_date, "ec", layer=layer)
    name_b1 = self.nameRelate(the_date, cate="gfs", layer=layer)
    name_a2 = self.nameRelate(the_date, cate="T639", layer=layer)
    self.CanvasStatus['imgAlbum'] = {}
    pics = self.name2pic([name_a1, name_b1, name_a2])
    texts = self.selectTexts(layer=layer, mode="climate")
    size = self.CanvasStatus['Draw_options']["size"]
    self.canvas.Draw(size=size, images=pics, texts=texts)

  def SwitchTime(self):
    print "MainWindow.SwitchTime be called"
    the_date = self.CanvasStatus["date"]
    layer = self.CanvasStatus["layer"].upper()
    mode = self.CanvasStatus["mode"].upper()
    full = self.CanvasStatus["whether_full"]
    grid = self.CanvasStatus["grid"].lower()
    region = self.CanvasStatus['region']
    name_a1 = name_a2 = name_b1 = ''
    if the_date[1] == "08": the_date[1] = "20"
    elif the_date[1] == "20": the_date[1] = "08"
    if mode == 'REGION' or mode == 'CLIMATE':
      name_a1 = self.nameRelate(the_date, "ec", layer=layer, region=region)
      name_b1 = self.nameRelate(the_date, cate="gfs", layer=layer, region=region)
    elif mode == 'RAIN':
      name_a1 = self.nameRelate(date=the_date, cate='GERMANY', layer=layer)
      name_a2 = self.nameRelate(date=the_date, cate='JAPAN', layer=layer)
    if layer in ['C' + str(i) for i in range(0, 17)]:
      name_a2 = self.nameRelate(the_date, cate="T639", layer=layer, region=region)
    elif mode == 'REGION' and layer in ['C18', 'C17']:
      name_a2 = self.nameRelate(the_date, cate='GFS', layer='C18', region=region)
    if name_a1: the_date = self.name2date(name_a1)
    elif name_b1: the_date = self.name2date(name_b1)
    elif name_a2: the_date = self.name2date(name_a2)
    else:
      the_date = self.CanvasStatus["date"]
      if the_date[1] == "08": the_date[1] = "20"
      elif the_date[1] == "20": the_date[1] = "08" 
      return None
    if full: the_num = {'a1': 0, 'b1': 1, 'a2': 2}[grid]
    if full and not [name_a1, name_b1, name_a2][the_num]:
      the_date = self.CanvasStatus["date"]
      if the_date[1] == "08": the_date[1] = "20"
      elif the_date[1] == "20": the_date[1] = "08" 
      return None
    self.CanvasStatus.update({"date": the_date, "layer": layer})
    self.CanvasStatus['imgAlbum'] = {}
    pics = self.name2pic([name_a1, name_b1, name_a2])
    if full:
      grid = self.CanvasStatus['grid']
      if grid == 'a1': name = name_a1
      elif grid == 'b1': name = name_b1
      elif grid == 'a2': name = name_a2
      pics.update(self.name2pic([name], full=full))
    texts = self.selectTexts(layer=layer, mode=mode, region=region)
    size = self.CanvasStatus['Draw_options']["size"]
    self.canvas.Draw(size=size, images=pics, texts=texts, full=full)

  def PageDown(self):
    print "MainWindow.PageDown be called"
    the_date = copy.deepcopy(self.CanvasStatus["date"])
    layer = self.CanvasStatus["layer"].upper()
    mode = self.CanvasStatus["mode"].upper()
    full = self.CanvasStatus["whether_full"]
    grid = self.CanvasStatus['grid']
    if layer in ['C17', 'C18'] and mode == 'REGION':
      # REGION
      region_name = self.CanvasStatus['region']
      the_order = self.regionName_order.index(region_name)
      if the_order + 1 < len(self.regionName_order):
        the_order += 1
      the_region = self.regionName_order[the_order]
      self.drawRegion(region=the_region, date=the_date)
      return None
    elif mode == 'RAIN':
      # RAIN
      delta = int(layer)
      the_date = copy.deepcopy(self.CanvasStatus["date"])
      new_date = int(the_date[2]) + delta
      if new_date > 168: return None
      else: the_date[2] = self.IntStr(new_date, dec=3)
      name_a1 = self.date2name(date=the_date, cate='GERMANY', layer=layer)
      name_b1 = self.nameRelate(date=the_date, cate='JAPAN', layer=layer)
      if self.WhetherNameExisted(name_a1) \
          or self.WhetherNameExisted(name_b1):
        self.CanvasStatus.update({"date": the_date, "layer": layer})
        self.DrawRain(layer=layer, date=the_date)
      return None
    elif layer in ['C' + str(i) for i in range(0, 17)] and mode == 'CLIMATE':
      # CLIMATE
      delta = 24
      the_date = copy.deepcopy(self.CanvasStatus["date"])
      new_date = int(the_date[2]) + delta
      if new_date > 168: return None 
      else: the_date[2] = self.IntStr(new_date, dec=3)
      # draw every canvas is order to update the draw_options
      name_a1 = self.nameRelate(the_date, "ec", layer=layer)
      name_b1 = self.nameRelate(the_date, cate="gfs", layer=layer)
      name_a2 = self.nameRelate(the_date, cate="T639", layer=layer)
      if self.WhetherNameExisted(name_a1) \
          or self.WhetherNameExisted(name_b1) \
          or self.WhetherNameExisted(name_a2):
        self.CanvasStatus.update({"date": the_date, "layer": layer})
      else: return None
      self.CanvasStatus['imgAlbum'] = {}
      pics = self.name2pic([name_a1, name_b1, name_a2])
      if full:
        pics.update({'full': pics[grid]})
      texts = self.selectTexts(layer=layer, mode="climate")
      size = self.CanvasStatus['Draw_options']["size"]
      self.canvas.Draw(size=size, images=pics, texts=texts, full=full)

  def WhetherNameExisted(self, name):
    print 'MainWindow.WhetherNameExisted be called'
    print '\t|name: %s' % name
    if not name: return False
    name_path = self.name2path(name)
    if os.path.isfile(name_path): return True
    else: return False

  def grid2cate(self, grid, mode='climate'):
    """
    mode = 'CLIMATE/REGION/RAIN'
    """
    print 'MainWindow.grid2cate be called'
    print '\t|grid: %s\n\t|mode: %s' %(repr(grid), repr(mode))
    mode = mode.lower()
    grid = grid.lower()
    if mode == 'climate':
      if grid == 'a1': return 'EC'
      if grid == 'b1': return 'GFS'
      if grid == 'a2': return 'T639'
    elif mode == 'region':
      if grid == 'a1': return 'EC'
      if grid == 'b1': return 'GFS'
      if grid == 'a2': return 'GFS'
    elif mode == 'rain':
      if grid == 'a1': return 'GERMANY'
      if grid == 'b1': return 'JAPAN'

  def PageUp(self):
    print "MainWindow.PageDown be called"
    the_date = copy.deepcopy(self.CanvasStatus["date"])
    layer = self.CanvasStatus["layer"].upper()
    mode = self.CanvasStatus["mode"].upper()
    full = self.CanvasStatus["whether_full"]
    grid = self.CanvasStatus['grid']
    if layer in ['C17', 'C18'] and mode == 'REGION':
      # REGION
      region_name = self.CanvasStatus['region']
      the_order = self.regionName_order.index(region_name)
      if the_order - 1 >= 0:
        the_order -= 1
      the_region = self.regionName_order[the_order]
      self.drawRegion(region=the_region, date=the_date)
      return None
    elif mode == 'RAIN':
      # RAIN
      delta = int(layer)
      the_date = copy.deepcopy(self.CanvasStatus["date"])
      new_date = int(the_date[2]) - delta
      if new_date < 0: return None
      else: the_date[2] = self.IntStr(new_date, dec=3)
      name_a1 = self.nameRelate(date=the_date, cate='GERMANY', layer=layer)
      name_b1 = self.nameRelate(date=the_date, cate='JAPAN', layer=layer)
      if self.WhetherNameExisted(name_a1) \
          or self.WhetherNameExisted(name_b1):
        self.CanvasStatus.update({"date": the_date, "layer": layer})
        self.DrawRain(layer=layer, date=the_date)
      return None
    elif layer in ['C' + str(i) for i in range(0, 17)] and mode == 'CLIMATE':
      # CLIMATE
      delta = -24
      the_date = copy.deepcopy(self.CanvasStatus["date"])
      new_date = int(the_date[2]) + delta
      if new_date < 0: return None
      else: the_date[2] = self.IntStr(new_date, dec=3)
      name_a1 = self.nameRelate(the_date, "ec", layer=layer)
      name_b1 = self.nameRelate(the_date, cate="gfs", layer=layer)
      name_a2 = self.nameRelate(the_date, cate="T639", layer=layer)
      if self.WhetherNameExisted(name_a1) \
          or self.WhetherNameExisted(name_b1) \
          or self.WhetherNameExisted(name_a2):
        self.CanvasStatus.update({"date": the_date, "layer": layer})
      else: return None
      self.CanvasStatus['imgAlbum'] = {}
      # draw every canvas is purpose to update the draw_options
      pics = self.name2pic([name_a1, name_b1, name_a2])
      if full:
        pics.update({'full': pics[grid]})
    texts = self.selectTexts(layer=layer, mode="climate")
    size = self.CanvasStatus['Draw_options']["size"]
    self.canvas.Draw(size=size, images=pics, texts=texts, full=full)
    
  def selectTexts(self, layer, mode="CLIMATE", region=None):
    """
    imput
      mode="CLIMATE" : ["CLIMATE"/"RAIN"/"REGION"]
    """
    print "MainWindow.selectTexts be called"
    print '\t|layer: %s\n\t|mode: %s\n\t|region: %s' %(layer, mode, region)
    grid = self.canvasGrid
    date = self.CanvasStatus["date"] 
    if region and mode.upper() == 'REGION':
      region_name = self.regionName[region.lower()]
      ans = region_name + '_' + date[1] + '\u65f6'
    elif mode.upper() == "CLIMATE":
      the_datetime = self.dateswitch(date)
      the_time = date[1]
      the_life = int(date[2])
      days = int(the_life / 24)
      the_datetime = the_datetime + datetime.timedelta(days=days)
      date = self.dateswitch(the_datetime, time=the_time, life=str(the_life))
      ans = "%s\u5e74%s\u6708%s\u65e5_%s\u65f6" \
          % (the_datetime.year, the_datetime.month, the_datetime.day, date[1])
    elif mode.upper() == 'RAIN':
      the_time = date[1]
      the_life = int(date[2])
      [the_datetime, hours] = self.LifePass(date)
      ans = "%s\u5e74%s\u6708%s\u65e5_%s\u65f6" \
          % (the_datetime.year, the_datetime.month, the_datetime.day, hours)
    return ans

  def LifePass(self, date):
    """
    return [thedate, hours] = date(datetime.date) + step(hr)
    """
    print "MainWindow.LifePass be called"
    print "\t|date: %s" %(repr(date))
    the_datetime = self.dateswitch(date)
    the_time = int(date[1])
    the_life = int(date[2])
    hours = the_time + the_life
    days = hours / 24
    hours = hours % 24
    the_date = the_datetime + datetime.timedelta(days=days)
    return [the_date, hours]
 
  def IntStr(self, num, dec=None):
    """
    return a str(int), in dec character
    """
    print 'MainWindow.IntStr be called'
    print '\t|num: %s\n\t|dec: %s' %(repr(num), repr(dec))
    num = int(num) # important to prevent "0 - 6"
    if not dec: return str(num)
    if dec <= len(str(num)):
      return str(num)
    ans = "0" * (dec - (len(str(num)))) + str(num)
    return ans

  def name2pic(self, names, full=None):
    """
    img is a PIL.Image instance
    pic is a PIL.ImageTk.PhotoImage instance
    ----------------------
    input:
      names - list: [name1, name2, ...]
      cates - list: ["ec", "t639", ...]
    return:
      dict: {"a1": pic1, "a2": pic2, ...}
    """
    print "MainWindow.name2pic be called"
    print '\t|names: %s\n\t|full: %s' %(repr(names), repr(full))
    ans = {}
    grid = self.canvasGrid
    for name in names:
      if not name: continue
      the_file = self.name2path(name)
      cate = name.split("-")[0].upper()
      img = Image.open(the_file)
      pic = ImageTk.PhotoImage(img)
      mode = self.CanvasStatus['mode']
      self.CanvasStatus['imgAlbum'].update({pic: img})
      layer = name.split('_')[0].split('-')[1]
      if not full:
        if layer in [str(i) for i in range(0, 18)]:
          ans.update({grid[cate]: pic})
        elif layer in ['18'] and mode == 'REGION':
          ans.update({'a2': pic})
        elif layer in ['06', '12', '24'] and mode == 'RAIN':
          ans.update({grid[cate]: pic})
      else:
        return {'full': pic}
    return ans

  def shuchu(self):
    print ">>>", self.CanvasStatus
       
  def name2path(self, name):
    """
    return:
      str: image's path
    """
    print "MainWindow.name2path be called"
    print '\t|name: %s' % repr(name)
    cate = name.split("-")[0]
    date = self.name2date(name)
    region=None
    if cate in ['GERMANY', 'JAPAN']:
      # RAIN layer
      layer = name.split('-')[1][: 2]
    else: 
      # REGION and CLIMATE layer
      layer = "C" + name.split("_")[0].split("-")[1]
    if layer in ['C17', 'C18']:
      region = name.split('-')[2].split('.')[0]
    prepath = self.prepath(cate, time=date[1], layer=layer, region=region)
    path = os.path.join(prepath, name)
    return path

  def lastdate(self, cate, time="08", layer="C0", region=None):
    """
    input:
      cate: "T639/EC/GFS/JAPAN/GERMANY"
    return:
      date: ["yyyymmdd", "time", "life"]
    """
    print "MainWindow.lastdate be called"
    print '\t|cate: %s\n\t|time: %s\n\t|layer: %s\n\t|region: %s' \
        %(cate, time, layer, region)
    path = self.prepath(cate.upper(), time=time, region=region, layer=layer)
    path = self.pathSwitch(path)
    if region:
      if not os.path.exists(path): return None
      the_file = os.walk(path).next()[2][0]
      date = self.name2date(the_file)
      return date
    if os.path.exists(path):
      the_files = os.walk(path).next()[2]
      the_files.sort()
      the_file = the_files[0]
      date = self.name2date(the_file)
      return date
    elif time != '20':
      ans = self.lastdate(cate=cate, time="20", layer=layer)
      if not ans: return None
      self.CanvasStatus["date"][1] = "20"
      return ans
    return None

  def prepath(self, cate, time="08", layer="C0", region=None):
    """
    input:
      cate: "T639/EC/GFS/GERMANY/JAPAN"
    return:
      str: the prepath
    """
    print "MainWindow.prepath be called"
    print '\t|cate: %s\n\t|time: %s\n\t|layer: %s\n\t|region: %s' \
        %(cate, time, layer, region)
    prepath = self.imgPath
    cate = cate.upper()
    layer = layer.upper()
    path = ''
    if layer in ['C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7']:
      path = os.path.join(prepath, cate, cate+time, layer)
    elif layer in ['C8', 'C9', 'C10']:
      path = os.path.join(prepath, cate, cate+time, 'C8')
      if layer == "C8": path = os.path.join(path, "500")
      if layer == "C9": path = os.path.join(path, "700")
      if layer == "C10": path = os.path.join(path, "850")
    elif layer in ['C11', 'C12', 'C13']:
      path = os.path.join(prepath, cate, cate+time, 'C9')
      if layer == "C11": path = os.path.join(path, "500")
      if layer == "C12": path = os.path.join(path, "700")
      if layer == "C13": path = os.path.join(path, "850")
    elif layer in ['C14', 'C15', 'C16']:
      path = os.path.join(prepath, cate, cate+time, 'C10')
      if layer == "C14": path = os.path.join(path, "500")
      if layer == "C15": path = os.path.join(path, "700")
      if layer == "C16": path = os.path.join(path, "850")
    elif layer in ["C17"] and region:
      path = os.path.join(prepath, cate, cate+time, 'C11')
    elif layer in ['C18'] and region and cate == 'GFS':
      path = os.path.join(prepath, cate, cate+time, 'C12')
    elif layer in ['06', '12', '24'] and cate in ['GERMANY', 'JAPAN']:
      path = os.path.join(prepath, cate, cate+time, layer)
    return path 

  def dateswitch(self, date, time="08", life="000"):
    """
    switch the  ["yyyymmdd", "time", "life"] with the datetime.date
    """
    print "MainWindow.dateswitch be called"
    print '\t|date: %s\n\t|time: %s\n\t|life: %s' \
        %(repr(date), time, life)
    if isinstance(date, list):
      yy = int(date[0][: 4])
      mon = int(date[0][4: 6])
      day = int(date[0][6: 8])
      return datetime.date(yy, mon, day)
    elif isinstance(date, datetime.date):
      yyyy = str(date.year)
      mm = self.IntStr(date.month, dec=2)
      dd = self.IntStr(date.day, dec=2)
      return [yyyy+mm+dd, time, life]

  def updateImagesize(self, pic, size):
    print "MainWindow.updateImagesize be called"
    print '\t|pic: %s\n\t|size: %s' %(repr(pic), repr(size))
    img = self.CanvasStatus['imgAlbum'][pic]
    [width, height] = size
    newimg = img.convert("RGB")
    newimg.thumbnail((width, height), Image.ANTIALIAS)
    newpic = ImageTk.PhotoImage(newimg)
    del self.CanvasStatus['imgAlbum'][pic]
    self.CanvasStatus['imgAlbum'].update({newpic: img})
    return newpic

  def Image2Clipboard(self, event=None):
    print 'MainWindow.Image2Clipboard be called'
    print '\t|event: %s' %repr(event)
    if not event: return None
    pointer = [event.x_root, event.y_root]
    pic = self.canvas.master.winfo_containing(pointer[0], pointer[1])
    if str(pic) not in self.CanvasStatus['cavs_imgAlbum']: return None
    img = self.CanvasStatus['cavs_imgAlbum'][str(pic)]
    if img not in self.CanvasStatus['imgAlbum']: return None
    img = self.CanvasStatus['imgAlbum'][img]
    output = StringIO()
    img.convert("RGB").save(output, "BMP")
    data = output.getvalue()[14:]
    output.close()
    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data)
    win32clipboard.CloseClipboard()

  def name2date(self, name):
    """
    return ["yyyymmdd", "time", "life"]
    """
    print "MainWindow.name2date be called"
    print '\t|name; %s' % repr(name)
    layer = name.split('_')[0].split('-')[1]
    date = name.split("_")[1][: 8]
    time = name.split("_")[1][8: 10]
    cate = name.split('-')[0].upper()
    if layer in [str(i) for i in range(0, 17)] \
        and cate in ['EC', 'GFS', 'T639']:
      life = name.split("_")[2].split(".")[0]
    elif layer in ["17", '18']:
      life = "000"
    elif layer in ['06', '12', '24']: # RAIN
      life = name.split("_")[2].split(".")[0]
      if cate == 'JAPAN' and layer == '06': 
        life = self.IntStr(int(life) - 6, dec=3)
      elif layer == '12':
        life = self.IntStr(int(life) - 12, dec=3)
      elif layer == '24':
        life = self.IntStr(int(life) - 24, dec=3)
    return [date, time, life]

  def date2name(self, date, cate, layer="C0", region=None):
    """
    date: ["yyyymmdd", "time", "life"]
    cate: "T639/EC/GFS/GERMANY/JAPAN"
    return a file name
    """
    print "MainWindow.date2name be called"
    if not isinstance(date, list):
      print "MainWindow.date2name.ParameterError"
    print '\t|date: %s\n\t|cate: %s\n\t|layer: %s\n\t|region: %s' \
        %(repr(date), cate, layer, region)
    name = None
    cate = cate.upper()
    if cate in ['T639', 'EC', 'GFS']: layer = layer[1: ]
    if layer in [str(i) for i in range(0, 17)] \
        and cate in ['T639', 'EC', 'GFS']:
      name = cate + '-' + layer +"_" + date[0] + date[1] + '_' + date[2] \
             + '.gif'
    elif layer in ["17", '18'] and region:
      name = cate + '-' + layer + '_' + date[0] + date[1] + '-' + region \
             + '.gif'
    elif layer in ['06', '12', '24'] and cate in ['JAPAN', 'GERMANY']:
      the_date = copy.deepcopy(date)
      if layer == '06' and cate == 'JAPAN': 
        the_date[2] = self.IntStr(int(the_date[2]) + 6, dec=3)
      elif layer == '12':
        the_date[2] = self.IntStr(int(the_date[2]) + 12, dec=3)
      elif layer == '24':
        the_date[2] = self.IntStr(int(the_date[2]) + 24, dec=3)
      name = cate + '-' + layer + '_' + the_date[0] + the_date[1] + '_' \
          + the_date[2] + '.gif'
    if not name:
      print "MainWindow.date2name.ParameterError\t",
    return name

  def nameRelate(self, date, cate, layer="C0", region=None):
    """
    input:
      date: ["yyyymmdd", "time", "life"]
      cate: "T639/EC/GFS/GERMANY/JAPAN"
    return:
      ["name_ec", "name_gfs", "name_t639"]
    """
    print "MainWindow.nameRelate be called"
    print '\t|date: %s\n\t|cate: %s\n\t|layer: %s\n\t|region: %s' \
        %(repr(date), cate, layer, region)
    cate = cate.upper()
    if region: region = region.lower()
    the_date = copy.deepcopy(date)
    #if cate == 'JAPAN' and layer == '06':
      # there is something wrong in the original data
    #  the_life = int(the_date[2]) + 6
    #  the_date[2] = self.IntStr(the_life, dec=3)
    name = self.date2name(the_date, cate, layer=layer, region=region)
    path = self.prepath(cate, time=the_date[1], layer=layer, region=region)  
    if os.path.isfile(os.path.join(path, name)):
      return name
    start = self.dateswitch(the_date)
    the_datetime = start
    the_date = copy.deepcopy(date)
    while abs((start - the_datetime).days) <= 2: 
      the_life = the_date[2]
      the_time = the_date[1]
      the_datetime = the_datetime - datetime.timedelta(days=1)
      the_life = self.IntStr(int(the_life) + 24, dec=3)
      the_date = self.dateswitch(the_datetime, time=the_time, life=the_life)
      name = self.date2name(the_date, cate, layer=layer, region=region)
      path = self.prepath(cate, time=the_date[1], layer=layer, region=region)
      if os.path.isfile(os.path.join(path, name)): 
        return name
    start = self.dateswitch(date)
    the_datetime = start
    the_date = copy.deepcopy(date)
    while abs((start - the_datetime).days) <= 2: 
      the_life = the_date[2]
      the_time = the_date[1]
      the_datetime = the_datetime + datetime.timedelta(days=1)
      if layer in ['C' + str(i) for i in range(0, 17)]:
        if int(the_life) - 24 < 0: return None
      the_life = self.IntStr(int(the_life) - 24, dec=3)
      the_date = self.dateswitch(the_datetime, time=the_time, life=the_life)
      name = self.date2name(the_date, cate, layer=layer, region=region)
      path = self.prepath(cate, time=the_date[1], layer=layer, region=region)
      if os.path.isfile(os.path.join(path, name)): 
        return name
    return None


errorCount = 0
if __name__ == "__main__":
  while True:
    try:
      aa = MainWindow()
      os._exit(0)
    except Exception, e:
      print "Main.Error: ", repr(e)
      errorCount += 1
      #raw_input()
      if errorCount > 20: os._exit(1)
